home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / prog / yamp2.zip / VIRTGRAF.CPP < prev    next >
C/C++ Source or Header  |  1992-01-17  |  18KB  |  676 lines

  1.  
  2. /*
  3. YAMP - Yet Another Matrix Program
  4. Version: 1.2
  5. Author: Mark Von Tress, Ph.D.
  6. Date: 01/23/92
  7.  
  8. Copyright(c) Mark Von Tress 1992
  9. Portions of this code are (c) 1991 by Allen I. Holub and are used by
  10. permission
  11.  
  12. DISCLAIMER: THIS PROGRAM IS PROVIDED AS IS, WITHOUT ANY
  13. WARRANTY, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  14. TO FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR DISCLAIMS
  15. ALL LIABILITY FOR DIRECT OR CONSEQUENTIAL DAMAGES RESULTING
  16. FROM USE OF THIS PROGRAM.
  17.  
  18. */
  19.  
  20. #include "virt.h"
  21.  
  22. Axis::Axis( VMatrix &grf_vec, int col, int pixels, int pxlspplot)
  23. {
  24.     Dispatch->Inclevel();
  25.     getlinesettings( &lineinfo );
  26.     valmin=0;
  27.     step=0;
  28.     ir=0;
  29.     ifault=0;
  30.     iv=30;
  31.     maxpr = 6;
  32.     mpv=pxlspplot;
  33.     fmn = fmx = grf_vec.m(1,col);
  34.     double temp;
  35.     for( int i=2; i<=grf_vec.r; i++){
  36.        temp = grf_vec.m(i,col);
  37.        fmn = ( temp < fmn ) ? temp : fmn;
  38.        fmx = ( temp > fmx ) ? temp : fmx;
  39.     }
  40.     if( fmn == fmx ){
  41.       fmx = fmn + 0.5;
  42.       fmn = fmn - 0.5;
  43.     }
  44.  
  45.     vals = new double[iv];
  46.     getvals( fmn, fmx, pixels, vals, &offset, &ifact, &nvals, &irprin);
  47.     Vals = new VMatrix;
  48.     *Vals = Fill( nvals,1, 0);
  49.       for( i=0; i < nvals; i++){
  50.          double temp = (irprin != 0 )?
  51.             floor( 0.5 + vals[i]*exp(((double)irprin)*log(10.0)) )
  52.                  *exp(-((double)irprin)*log(10.0)):
  53.             vals[i];
  54.          Vals->M(i+1,1) = temp;
  55.       }
  56.      Dispatch->Declevel();
  57.  
  58. }
  59. Axis::~Axis( void )
  60. {
  61.     delete vals;
  62.     delete Vals;
  63. }
  64. double Axis::dmax( double x, double y )
  65. {
  66.    return ( (x>y) ? x: y);
  67. }
  68.  
  69. void Axis::scale(double fmn, double fmx, int n, int mpv,
  70.            double *valmin, double *step, int *nvals,int *ir, int *ifault)
  71.  
  72.   { double unit[13]={ 0, 12,15,20,25,30,40,50,60,80,100,120,150};
  73.     double tol = 5.0e-6, bias = 1.0e-5, cover = 0.7, temp;
  74.     int i,j,minn = 2, maxn = 10000;
  75.     char buf[80] = {'\0'};
  76.  
  77.     double fmax, fmin, finter, s, aj, tstep;
  78.     int nunit = 12;
  79.  
  80.     fmax = fmx;
  81.     fmin = fmn;
  82.     *ifault = 0;
  83.     if (fmax < fmin) *ifault++;
  84.     if ( (n<minn)||(n>maxn)) *ifault += 2;
  85.     if ((mpv<=0)||(mpv>=n)) *ifault += 4;
  86.     if (*ifault) {
  87.        sprintf(buf, "SCALE: bad parameters in scale irprn = %d", *ifault);
  88.        closegraph();
  89.        Dispatch->Nrerror( buf );
  90.     }
  91.     *nvals = 1+(n-1)/mpv;
  92.     if ((fmax-fmin)<=(tol*((double)dmax(fabs(fmax),fabs(fmin))))){
  93.       *ifault = -1;
  94.       if(fmax<0) fmax = 0;
  95.       if(fmax==0) fmax = 1;
  96.       if(fmax>0) fmin = 0;
  97.     }
  98.     finter = ((double)n)/((double)mpv);
  99.     s = (fmax-fmin)*(1.0+2.0*bias)/finter;
  100.     *ir = 0;
  101.     while( s <= 10.0){
  102.        s *= 10;
  103.        (*ir)++;
  104.     }
  105.     while(s > 100 ) {
  106.        s /= 10;
  107.        (*ir)--;
  108.     }
  109.     i=0;
  110.     while( s > unit[i] ) i++;
  111.  
  112.    LABEL1:
  113.     *step = unit[i]*exp( -((double)(*ir))*log(10) );
  114.     aj = 0;
  115.  
  116.    LABEL2:
  117.     do{
  118.        aj += 1.0;
  119.     }  while( (unit[i]-0.1) > ( floor((unit[i]+0.1)/aj)*aj ) );
  120.     tstep = (*step)/aj;
  121.     temp = fmin/tstep + aj*( 0.5/((double)mpv) - finter*bias);
  122.     *valmin = floor(temp)*tstep;
  123.     if( (temp<0) && (temp!=floor(temp))) (*valmin) -= tstep;
  124.     if (fmax < ((*valmin)+(*step)*(finter*(1.0-bias)-0.5/ ((double)mpv) ) ))
  125.        goto LABEL3;
  126.     if((unit[i]/unit[i+1]*(1.0-1.0/(aj*finter))) < cover) goto LABEL2;
  127.     i++;
  128.     if( i == nunit ) printf("problem");
  129.     goto LABEL1;
  130.    LABEL3:
  131.     for( j=1; j<=2; j++){
  132.       aj *= 10;
  133.       if( (unit[i] - 0.1 ) < ( floor((unit[i]+0.1)/aj)*aj) )  (*ir) -= 1;
  134.    }
  135. }   /* scale */
  136.  
  137.  
  138.  
  139. void Axis::axis(double valmin,double step,int nvals, int maxpr,int ir,
  140.           int *irprin, double *offset, int *ifact, double *vals, int iv,
  141.           int * ifault)
  142.      {
  143.        int irmax = 200, mprmax = 20;
  144.        double fmax, tmax, fl, fs, vstep,vmin, temp1=0, temp2=0;
  145.        double dtemp1=0, dtemp2=0;
  146.        int i,il,is,it,ilprin;
  147.        char buf[80] = {'\0'};
  148.  
  149.        *ifault = 0;
  150.        if ( nvals < 2 ) (*ifault)++;
  151.        fmax = valmin + step*((double)(nvals-1));
  152.        if ( (nvals >= 2) && (fmax <= valmin)) (*ifault) += 2;
  153.        if ( (maxpr < 2) || (maxpr > mprmax) ) (*ifault) += 4;
  154.        if (nvals > iv) (*ifault) += 8;
  155.        if ( ir > irmax ) (*ifault) += 16;
  156.        if ( *ifault ){
  157.           sprintf(buf, "Axis: bad parameters in axis: error %d", *ifault);
  158.           closegraph();
  159.           Dispatch->Nrerror( buf );
  160.        }
  161.  
  162.        tmax = exp( ((double)maxpr)*log(10.0) );
  163.        fl = fabs(fmax);
  164.        fs = fabs(valmin);
  165.        il = 0;
  166.        while( !( (fl < 1.0)  && (fs < 1.0)) ){
  167.          fl /= 10;
  168.          fs /= 10;
  169.          il++;
  170.        }
  171.        while( !( (fl >= 0.1 ) || ( fs >= 0.1 )) ) {
  172.          fl *= 10;
  173.          fs *= 10;
  174.          il -= 1;
  175.        }
  176.  
  177.        is = il + ir;
  178.        it = is;
  179.        if ((valmin <= 0.0 ) && ( fmax >= 0.0) ) goto LABEL50;
  180.      LABEL40:
  181.         fl =((double) modf( fl, &dtemp1))*10;
  182.         fs =((double) modf( fs, &dtemp2))*10;
  183.         if ( it <= 0 ){
  184.            closegraph();
  185.            Dispatch->Nrerror( "Axis: error 16 in axis ");
  186.         }
  187.  
  188.       if ( ((int)floor( fl )) !=((int) floor(fs)) ) goto LABEL50;
  189.       it--;
  190.       goto LABEL40;
  191.  
  192.      LABEL50:
  193.      *ifact = 0;
  194.      *offset = 0.0;
  195.      *irprin = ( ir > 0 )? ir : 0;
  196.       ilprin = ( il > 0 )? il : 0;
  197.  
  198.      if (  ((*irprin)+ilprin) <= maxpr ) goto LABEL70;
  199.         if( is <= maxpr ) goto LABEL60;
  200.           *irprin = maxpr - 1;
  201.           *ifact =  (it > maxpr)? it: maxpr ;
  202.           *ifact = (*ifact) - 1 - ir;
  203.           goto LABEL70;
  204.         LABEL60:
  205.           *ifact = il -1;
  206.           *irprin = is - 1;
  207.       LABEL70:
  208.       fs = exp(-((double)(*ifact))*log(10.0) );
  209.       vstep = step*fs;
  210.       vmin = valmin*fs;
  211.       if (!( is <= maxpr)){
  212.          *offset = floor( vmin / 10.0)*10;
  213.          vmin -= (*offset);
  214.       }
  215.       for( i=0; i<nvals; i++){
  216.          vals[i] = vmin;
  217.          vmin += vstep;
  218.       }
  219.       fs = pow( 0.1, ((double)(*irprin)) );
  220.       temp1 = fabs( vals[0])*fs + 0.5;
  221.       temp2 = fabs( vals[nvals-1]) * fs + 0.5;
  222.      if ( (temp1 < tmax ) && (temp2 < tmax ) ) return;
  223.       il++;
  224.       is++;
  225.       it++;
  226.       goto LABEL50;
  227.  
  228.   } /* end axis */
  229.  
  230. /* get scale and axis Applied Statistics algorithm 168 */
  231.  
  232. void Axis::getvals(double fmn, double fmx, int n, double *vals,
  233.                    double *offset,int *ifact,int *nvals,int *irprin)
  234.  {
  235.  
  236.     scale(fmn, fmx, n, mpv, &valmin, &step, nvals, &ir, &ifault);
  237.     axis( valmin, step, *nvals, maxpr,ir, irprin, offset, ifact,
  238.       vals, iv, &ifault);
  239.  
  240.     //
  241.     // the following code fixes an axis where data is out of range
  242.     //
  243.  
  244.     double st = Rescale( step );
  245.     double t = Rescale( fmn );
  246.     double trace;
  247.     int down=0, up=0;
  248.  
  249.     if ( t < vals[0] )
  250.        for( trace = vals[0];(t < trace) && (down + *nvals < iv);
  251.             down++, trace -= st);
  252.  
  253.     t = Rescale( fmx );
  254.     if ( t > vals[*nvals-1] )
  255.        for( trace = vals[*nvals-1];(t > trace) && (up+down+*nvals < iv);
  256.         up++, trace += st);
  257.  
  258.     if( down+up+*nvals >= iv ){
  259.           // prevent a writeover past the end of vals
  260.           ifault = 8;
  261.           char buf[80] = { '\0' };
  262.           sprintf(buf, "Axis: bad parameters in axis: error %d", ifault);
  263.           closegraph();
  264.           Dispatch->Nrerror( buf );
  265.     }
  266.  
  267.     t = vals[0] - ((double) down)*st;
  268.     for( int i=0; i< down+up+*nvals; i++) {
  269.       vals[i] = t;
  270.       t+=st;
  271.     }
  272.     *nvals += down+up;
  273. }
  274. strtype Axis::GetAxisLabel( strtype &name)
  275. {
  276.     char xo[20]={'\0'}, xi[20]={'\0'};
  277.     char buf[80]={'\0'};
  278.     strtype newname;
  279.     newname = name + " ";
  280.  
  281.     gcvt(offset, 8, buf);
  282.     strcpy(xo,(const char *) buf);
  283.     gcvt(ifact, 8, buf);
  284.     strcpy(xi,(const char *) buf);
  285.     if ( offset && ifact )
  286.        newname = newname + "((x+" + xo +")*10**" + xi + ")";
  287.     if ( !offset && ifact )
  288.        newname = newname + "(x*10**" + xi + ")";
  289.     if ( offset && !ifact )
  290.        newname = newname + "(x+" + xo + ")";
  291.     return newname;
  292. }
  293. double Axis::Rescale( double x )
  294. {
  295.   static double log10 = log(10.0);
  296.   double xo = x+offset;
  297.   double si = ( xo <= 0.0 ) ? -1.0: 1.0;
  298.   double xv = ( xo == 0.0 ) ? 0.0 :
  299.          si*exp( log(fabs(xo))-((double)ifact)*log10 );
  300.   return xv;
  301. }
  302.  
  303.  
  304. //////////////////////// yaxis
  305.  
  306.  
  307. YAxis::YAxis( VMatrix &grf, int xxlen,  int yylen,  int ww, int hh,
  308.               int bbmarg,   int uumarg, int llmarg, int rrmarg):
  309.     Axis( grf, 4, yylen, yylen/hh  )
  310. {
  311.   Dispatch->Inclevel();
  312.   h = hh;
  313.   w = ww;
  314.   bmarg = bbmarg;
  315.   umarg = uumarg;
  316.   lmarg = llmarg;
  317.   rmarg = rrmarg;
  318.   ylen = yylen;
  319.   xlen = xxlen;
  320.  
  321.   maxy = (Mmax( *Vals )).m(3,1);
  322.   miny = (Mmin( *Vals )).m(3,1);
  323.  
  324.   deltay = ( fabs(maxy-miny) < 1.0e-10) ? 1.1*miny : maxy - miny;
  325.   deltay = ((double)ylen)/deltay;
  326.  
  327.   Dispatch->Cleanstack();
  328.   Dispatch->Declevel();
  329. }
  330.  
  331.  
  332.  
  333. void YAxis::Show( boolean gridon )
  334. {
  335.   // show yaxis
  336.  
  337.   char *buf = new char[80];
  338.   strtype *junk = new strtype;
  339.   setviewport( lmarg, umarg, rmarg, bmarg, 1 );
  340.   line( 0,0, 0, ylen+1);
  341.  
  342.   setviewport( 0, umarg-h, lmarg, bmarg+h, 1);
  343.   settextjustify( RIGHT_TEXT, CENTER_TEXT );
  344.  
  345.   int tickloc;
  346.   for( int i=1; i<=nvals; i++){
  347.      double temp = Vals->m(i,1);
  348.      tickloc =ylen-(int)( deltay*( temp - miny ) )+h;
  349.      gcvt( temp, (maxpr+2), buf);
  350.      *junk = "";
  351.      *junk = *junk + buf + " ";
  352.      outtextxy( lmarg, tickloc, junk->StringAddress() );
  353.      line( lmarg-w+1, tickloc-1, lmarg, tickloc-1 );
  354.   }
  355.   if( gridon ){
  356.     setviewport( lmarg, umarg-h, rmarg, bmarg+h, 1);
  357.     setlinestyle( lineinfo.linestyle, lineinfo.upattern, NORM_WIDTH);
  358.     for( int i=1; i<=nvals; i++){
  359.       double temp = Vals->m(i,1);
  360.       tickloc =ylen-(int)( deltay*( temp - miny ) )+h;
  361.       line( 0, tickloc-1, xlen, tickloc-1);
  362.  
  363.     }
  364.     setlinestyle( lineinfo.linestyle, lineinfo.upattern, THICK_WIDTH);
  365.   }
  366.  
  367.   setviewport( lmarg, umarg, rmarg, bmarg, 1 );
  368.   delete buf;
  369.   delete junk;
  370.  
  371.  
  372. }
  373. //////////// xaxis
  374.  
  375. XAxis::XAxis( VMatrix &grf, int xxlen,  int yylen, int ww, int hh,
  376.               int bbmarg,   int uumarg, int llmarg, int rrmarg):
  377.    Axis( grf, 3, xxlen, xxlen/ww )
  378. {
  379.   Dispatch->Inclevel();
  380.   xlen = xxlen;
  381.   ylen = yylen;
  382.   w = ww;
  383.   h = hh;
  384.   bmarg = bbmarg;
  385.   umarg = uumarg;
  386.   lmarg = llmarg;
  387.   rmarg = rrmarg;
  388.  
  389.   maxx = (Mmax( *Vals )).m(3,1);
  390.   minx = (Mmin( *Vals )).m(3,1);
  391.  
  392.   deltax = (fabs(maxx-minx) < 1.0e-10) ? 1.1*minx : maxx-minx;
  393.   deltax = ((double)xlen)/deltax;
  394.  
  395.   Dispatch->Cleanstack();
  396.   Dispatch->Declevel();
  397.  
  398. }
  399.  
  400. void XAxis::Show( boolean gridon )
  401. {
  402.   char *buf = new char[80];
  403.   setviewport( lmarg, umarg, rmarg, bmarg, 1 );
  404.   line( 0,ylen, xlen, ylen);
  405.  
  406.  
  407.   int mdelta = w*(maxpr+2)/2 + w;
  408.   setviewport( lmarg-mdelta, bmarg, rmarg+mdelta, bmarg+5*h, 1);
  409.   settextjustify( CENTER_TEXT, TOP_TEXT );
  410.  
  411.   int tickloc;
  412.   for( int i=1; i<=nvals; i++){
  413.     double temp = Vals->m(i,1);
  414.     tickloc = mdelta + (int)( deltax*(temp - minx ) );
  415.     gcvt( temp, (maxpr+2), buf);
  416.     outtextxy( tickloc , h, buf);
  417.     line( tickloc+1, 0, tickloc+1, h/2);
  418.   }
  419.  
  420.   if( gridon ){
  421.     setviewport( lmarg-mdelta, umarg, rmarg+mdelta, bmarg, 1);
  422.     setlinestyle( lineinfo.linestyle, lineinfo.upattern, NORM_WIDTH);
  423.     for( int i=1; i<=nvals; i++){
  424.       double temp = Vals->m(i,1);
  425.       tickloc = mdelta + (int)( deltax*(temp - minx ) );
  426.       line( tickloc+1, 0, tickloc+1, ylen);
  427.     }
  428.     setlinestyle( lineinfo.linestyle, lineinfo.upattern, THICK_WIDTH);
  429.   }
  430.  
  431.   setviewport( lmarg, umarg, rmarg, bmarg, 1 );
  432.   delete buf;
  433. }
  434.  
  435.  
  436. ///////////////////////////////  graph matrix class
  437.  
  438. GMatrix::GMatrix( void )
  439. {
  440.    title = new strtype;
  441.    title2= new strtype;
  442.    xname = new strtype;
  443.    yname = new strtype;
  444.    PathToDriver = new strtype;
  445.    hrefs = new double[20];
  446.    vrefs = new double[20];
  447.  
  448.  
  449.    graphnum = 0;
  450.    nhrefs = nvrefs = -1;
  451.    RectangleOn = TTRUE;
  452.    XGridOn = YGridOn = FFALSE;
  453.    grf = new VMatrix("graph", 1, 4);
  454. }
  455.  
  456. GMatrix::GMatrix( VMatrix &ROp, int symbol)
  457. {
  458.    Dispatch->Inclevel();
  459.  
  460.    nvrefs = nhrefs = -1;
  461.  
  462.    title = new strtype;
  463.    *title = ROp.Getname(ROp);
  464.    title2= new strtype;
  465.    xname = new strtype;
  466.    yname = new strtype;
  467.    PathToDriver = new strtype;
  468.    hrefs = new double[20];
  469.    vrefs = new double[20];
  470.  
  471.    graphnum = 1;
  472.    RectangleOn = TTRUE;
  473.    XGridOn = YGridOn = FFALSE;
  474.    grf = new VMatrix("graph", 1, 4);
  475.    int n = ROp.r;
  476.    printf("\nMaking a Graph\n");
  477.    *grf =
  478.       Ch( Fill(n,1, (double)graphnum), Ch(Fill(n,1, (double)symbol), ROp));
  479.    Dispatch->Declevel();
  480. }
  481.  
  482. GMatrix::~GMatrix( void )
  483. {
  484.    delete grf;
  485.    delete title;
  486.    delete title2;
  487.    delete xname;
  488.    delete yname;
  489.    delete PathToDriver;
  490.    delete hrefs;
  491.    delete vrefs;
  492. }
  493. void GMatrix::Href( double href )
  494. {
  495.   hrefs[ ++nhrefs % 20 ] = href;
  496. }
  497.  
  498. void GMatrix::Vref( double vref )
  499. {
  500.   vrefs[ ++nvrefs % 20 ] = vref;
  501. }
  502.  
  503.  
  504.  
  505. void GMatrix::AddVec( VMatrix &ROp, int symbol)
  506. {
  507.   Dispatch->Inclevel();
  508.   VMatrix *temp = new VMatrix;
  509.   graphnum++;
  510.   int n = ROp.r;
  511.   printf("\nAppending a new graph\n");
  512.   *temp =
  513.     Ch( Fill(n,1,(double)graphnum), Ch(Fill(n,1,(double)symbol), ROp));
  514.   *grf = Cv( *grf, *temp);
  515.   delete temp;
  516.   Dispatch->Declevel();
  517. }
  518.  
  519. int GMatrix::gprintf( int *xloc, int *yloc, char *fmt, ... )
  520. {
  521.   va_list  argptr;                        // Argument list pointer
  522.   char str[140];                        // Buffer to build sting into
  523.   int cnt;                                // Result of SPRINTF for return
  524.  
  525.   va_start( argptr, fmt );                // Initialize va_ functions
  526.  
  527.   cnt = vsprintf( str, fmt, argptr );    // prints string to buffer
  528.   outtextxy( *xloc, *yloc, str );       // Send string in graphics mode
  529.   *yloc += textheight( "H" ) + 2;       // Advance to next line
  530.   va_end( argptr );                        // Close va_ functions
  531.   return( cnt );                        // Return the conversion count
  532.  
  533. }
  534. void GMatrix::Pause(void)
  535. {
  536.   static char msg[] = "Esc aborts or press a key...";
  537.   int c;
  538.   c = getch();
  539.   if( 0x1b == c ){
  540.     closegraph();
  541.     exit( 1 );
  542.   }
  543.   if( 0 == c ){
  544.     c = getch();
  545.   }
  546.   cleardevice();
  547.   restorecrtmode();
  548. }
  549.  
  550. void GMatrix::plotpoint( int ix, int iy, int symbol )
  551. {
  552.    char str[2] = { (char) symbol, '\0'};
  553.    outtextxy( ix, iy, str );
  554. }
  555.  
  556. void GMatrix::Show( void )
  557. {
  558.  
  559.   Dispatch->Inclevel();
  560.   GraphDriver = DETECT;
  561.   // GraphDriver = CGA;
  562.   // GraphMode = CGAHI;
  563.   initgraph( &GraphDriver, &GraphMode, PathToDriver->StringAddress() );
  564.   ErrorCode = graphresult();
  565.   if( ErrorCode != grOk ){
  566.     printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
  567.     exit( 1 );
  568.   }
  569.  
  570.   cleardevice();
  571.   MaxColors = getmaxcolor() + 1;
  572.  
  573.   MaxX = getmaxx();
  574.   MaxY = getmaxy();            // Read size of screen
  575.  
  576.   getviewsettings( &viewinfo );
  577.   getlinesettings( &lineinfo );
  578.   setcolor( MaxColors -1 );
  579.   setviewport( 0,0, MaxX, MaxY, 1);
  580.  
  581.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  582.   int x = MaxX/2, y = 4;
  583.   gprintf( &x, &y,  title->StringAddress() );
  584.   gprintf( &x, &y, title2->StringAddress() );
  585.   int h = textheight( "H" );
  586.   int w = textwidth( "Z" );
  587.   int lmarg = 10*w, rmarg = MaxX - 10 * w, umarg = 5*h, bmarg = MaxY-5*h;
  588.  
  589.  
  590.   setviewport( lmarg, umarg-1, rmarg, bmarg, 1 );
  591.   getviewsettings( &viewinfo );
  592.   int xlen = viewinfo.right - viewinfo.left;
  593.   int ylen = viewinfo.bottom - viewinfo.top;
  594.  
  595.   setlinestyle( lineinfo.linestyle, lineinfo.upattern, THICK_WIDTH);
  596.   if( RectangleOn ) rectangle( 0,0, xlen, ylen);
  597.  
  598.  
  599. ///////////// draw axies
  600.   YAxis *yaxis = new YAxis( *grf, xlen, ylen, w, h, bmarg, umarg, lmarg, rmarg);
  601.   yaxis->Show(YGridOn);
  602.  
  603.   XAxis *xaxis = new XAxis( *grf, xlen, ylen, w, h, bmarg, umarg, lmarg, rmarg);
  604.   xaxis->Show(XGridOn);
  605.  
  606. ////////////// plot points
  607.  
  608.   setlinestyle( lineinfo.linestyle, lineinfo.upattern, NORM_WIDTH);
  609.  
  610.   setviewport( lmarg, umarg, rmarg, bmarg, 1 );
  611.   settextjustify( CENTER_TEXT, CENTER_TEXT );
  612.  
  613.   int lx, ly, ix, iy, cnter = 1;
  614.   boolean newgraph = TTRUE;
  615.   double deltax = ((double)xlen)/(xaxis->maxx - xaxis->minx);
  616.   double deltay = ((double)ylen)/(yaxis->maxy - yaxis->miny);
  617.   for( int i=1; i<=grf->r; i++){
  618.      if( cnter != ((int) grf->m(i,1) ) ){
  619.          cnter++;
  620.          newgraph = TTRUE;
  621.      }
  622.      double symbol = grf->m(i,2);
  623.      double tempx =  xaxis->Rescale(grf->m(i,3));
  624.      double tempy =  yaxis->Rescale(grf->m(i,4));
  625.      ix =        (int) ( ( tempx - xaxis->minx)*deltax );
  626.      iy = ylen - (int) ( ( tempy - yaxis->miny)*deltay );
  627.      plotpoint( ix, iy , abs(symbol) );
  628.      if( symbol <= 0.0 ){
  629.        if ( !newgraph ) line( lx, ly, ix, iy );
  630.        newgraph = FFALSE;
  631.      }
  632.      lx = ix;
  633.      ly = iy;
  634.   }
  635.  
  636.   if( nhrefs > -1 ){
  637.     int indx = ( nhrefs > 19 ) ? 19: nhrefs;
  638.     for( i=0; i<= indx; i++){
  639.       double temph = yaxis->Rescale(hrefs[i]);
  640.       iy =  ylen - ( (int) (( temph-yaxis->miny)*deltay) );
  641.       line( 0, iy, xlen, iy );
  642.     }
  643.   }
  644.   if( nvrefs > -1){
  645.     int indx = ( nvrefs > 19 ) ? 19: nvrefs;
  646.     for( i=0; i<= indx; i++){
  647.       double tempv = xaxis->Rescale(vrefs[i]);
  648.       ix = (int) ( (tempv - xaxis->minx)*deltax );
  649.       line( ix, 0, ix, ylen );
  650.     }
  651.   }
  652.  
  653. /////////// display axis labels
  654.   setviewport( 0,0, MaxX, MaxY, 1 );
  655.   strtype *ylabel = new strtype;
  656.   *ylabel = yaxis->GetAxisLabel( *yname );
  657.   x = lmarg;
  658.   y = umarg - h - 3;
  659.   gprintf( &x, &y, ylabel->StringAddress() );
  660.  
  661.   strtype *xlabel = new strtype;
  662.   *xlabel = xaxis->GetAxisLabel( *xname );
  663.   y = bmarg + 3*h + h/2 + 2;
  664.   x = MaxX/2;
  665.   gprintf(&x, &y, xlabel->StringAddress() );
  666.  
  667.   Pause();
  668.   delete xaxis;
  669.   delete yaxis;
  670.   delete xlabel;
  671.   delete ylabel;
  672.   Dispatch->Cleanstack();
  673.   Dispatch->Declevel();
  674.  
  675. }
  676.